/*
 * Copyright (c) 2011, Julien Lamy
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * Neither the name of the project's author nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "playlist.h"

#include <istream>
#include <sstream>
#include <stdexcept>
#include <stdint.h>

#include <iostream>

#include "playlist.h"
#include "dataobject.h"
#include "utils.h"

QString const Playlist::empty_string("");

Playlist::Playlist()
{
    // Nothing to do
}

Playlist::Playlist(std::istream & stream)
{
    if(!is_chunk_of_type(stream, "mhyp"))
    {
        throw std::runtime_error("Not a mhyp");
    }

    DEFINE_AND_READ(header_length, uint32_t, stream); // 8
    DEFINE_AND_READ(total_length, uint32_t, stream); // 12
    DEFINE_AND_READ(number_of_data_objects, uint32_t, stream); // 16
    DEFINE_AND_READ(number_of_playlist_items, uint32_t, stream); // 20
    DEFINE_AND_READ(is_master_playlist, uint8_t, stream); // 21
    DEFINE_AND_READ(unknown_1, uint8_t, stream); // 22
    DEFINE_AND_READ(unknown_2, uint8_t, stream); // 23
    DEFINE_AND_READ(unknown_3, uint8_t, stream); // 24
    DEFINE_AND_READ(timestamp, uint32_t, stream); // 28
    DEFINE_AND_READ(persistent_playlist_id, uint64_t, stream); // 36
    DEFINE_AND_READ(unknown_4, uint32_t, stream); // 40
    DEFINE_AND_READ(number_of_string_data_objects, uint16_t, stream); // 42
    DEFINE_AND_READ(is_podcast, uint8_t, stream); // 43
    DEFINE_AND_READ(is_group, uint8_t, stream); // 44
    DEFINE_AND_READ(list_sort_order, uint32_t, stream); // 48

    stream.ignore(header_length-48);

    std::cout << number_of_data_objects << " data objects\n";
    std::cout << number_of_playlist_items << " playlist items\n";

    for(unsigned int i=0; i<number_of_data_objects; ++i)
    {
        stream.seekg(12, std::ios::cur);
        DEFINE_AND_READ(type, uint32_t, stream);
        stream.seekg(-16, std::ios::cur);

        if(type != 15 && type != 16 && type != 17 && type != 50 && type != 51 &&
           type != 52 && type != 53 && type != 100)
        {
            DataObject<QString> data_object;
            stream >> data_object;
        }
        else
        {
            std::ostringstream message;
            message << "Cannot parse DataObject of type " << type;
            throw std::runtime_error(message.str());
        }
    }
}

QString const & Playlist::operator[](DataObjectType::Type type) const
{
    std::map<DataObjectType::Type, QString>::const_iterator it =
        this->strings_.find(type);

    if(it != this->strings_.end())
    {
        return it->second;
    }
    else
    {
        return this->empty_string;
    }
}
